/*
Kakine
ActionScript Framework
Copyright © 2011, PUNY, LLC.

This file is part of KAKINE.

KAKINE is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

KAKINE is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with KAKINE.  If not, see <http://www.gnu.org/licenses/>.
*/ 
package com.puny.ball.views.obstacles
{
	import com.puny.ball.utils.CollisionPL;
	import com.puny.ball.utils.ICollision;
	import com.puny.ball.utils.Vector2D;
	
	import flash.geom.Matrix;
	import flash.geom.Rectangle;

	public class BoxShapeObstacle extends Obstacle
	{
		private const _wcpl:CollisionPL = new CollisionPL();
		private const _hcpl:CollisionPL = new CollisionPL();
		private const _topLeft:Vector2D = new Vector2D();
		private const _bottomLeft:Vector2D = new Vector2D();
		private const _topRight:Vector2D = new Vector2D();;
		private const _bottomRight:Vector2D = new Vector2D();
		private const _pos:Vector2D = new Vector2D();
		private const _wdir:Vector2D = new Vector2D();
		private const _hdir:Vector2D = new Vector2D();
		public function BoxShapeObstacle()
		{
			checkers = [[_wcpl, _topLeft, _bottomLeft],
						[_hcpl, _topLeft, _topRight]];
			super();
		}

		public function inflate(r:Number):void {
			var rect:Rectangle;
			rect = getBounds(this);
			var rsx:Number = r / scaleX;
			var rsy:Number = r / scaleY;
			rect.x -= rsx;
			rect.y -= rsy;
			rect.width += 2 * rsx;
			rect.height += 2 * rsy;
			
			_topLeft.x = calcX(rect.left, rect.top);
			_topLeft.y = calcY(rect.left, rect.top);
			_bottomLeft.x = calcX(rect.left, rect.bottom);
			_bottomLeft.y = calcY(rect.left, rect.bottom);
			_topRight.x = calcX(rect.right, rect.top);
			_topRight.y = calcY(rect.right, rect.top);
			_bottomRight.x = calcX(rect.right, rect.bottom);
			_bottomRight.y = calcY(rect.right, rect.bottom);
			
			_wdir.x = _topRight.x - _topLeft.x;
			_wdir.y = _topRight.y - _topLeft.y;
			_wcpl.dir = _wdir;
			_hdir.x = _bottomLeft.x - _topLeft.x;
			_hdir.y = _bottomLeft.y - _topLeft.y;
			_hcpl.dir = _hdir;
			
			drawDebugShape();
		}
		
		public function set elasticity(value:Number):void {
			_wcpl.e = value;
			_hcpl.e = value;
		}
		override protected function drawShape():void {
			shape.graphics.clear();
			shape.graphics.beginFill(0xFF0000,.5);
			shape.graphics.moveTo(_topLeft.x, _topLeft.y);
			shape.graphics.lineTo(_topRight.x, _topRight.y);
			shape.graphics.lineTo(_bottomRight.x, _bottomRight.y);
			shape.graphics.lineTo(_bottomLeft.x, _bottomLeft.y);
			shape.graphics.endFill();
		}
		
		protected function get topLeft():Vector2D {
			return _topLeft;
		}
		
		protected function get topRight():Vector2D {
			return _topRight;
		}
		
		protected function get bottomLeft():Vector2D {
			return _bottomLeft;
		}
		
		protected function get bottomRight():Vector2D {
			return _bottomRight;
		}
		
		protected function get wcpl():CollisionPL {
			return _wcpl
		}
		
		protected function get hcpl():CollisionPL {
			return _hcpl;
		}
		
		private function calcX(px:Number,py:Number):Number {
			var matrix:Matrix = transform.matrix;
			return matrix.a * px - matrix.b * py + matrix.tx;
		}
		
		private function calcY(px:Number, py:Number):Number {
			var matrix:Matrix = transform.matrix;
			return -matrix.c * px + matrix.d * py + matrix.ty;
		}
		
		override public function collision(org:Vector2D,dir:Vector2D):Boolean {
			pos = Infinity;
			var checker:ICollision
			for(var i:int = 0;i < 2;i++) {
				checker = checkers[i][0];
				if (checker.setParticle(org,dir)) {
					collisionWithLine(checker as CollisionPL,checkers[i][1]);
					collisionWithLine(checker as CollisionPL,checkers[i][2]);
				}
			}
			if (pos != Infinity) {
				_pos.x = org.x + pos * dir.x;
				_pos.y = org.y + pos * dir.y;
				hitPos = _pos;
			}
			return pos != Infinity;
		}
		
		protected function collisionWithLine(checker:CollisionPL,pt:Vector2D):Boolean {
			var t:Number;
			checker.r = pt;
			t = checker.collisionPoint();
			if (t < pos) {
				pos = t;
				newPos = checker.reflex();
				mirroredPos = checker.mirror();
//				trace("t=", pos, newPos, mirroredPos);
				return true;
			}
			return false;
		}

	}
}